package com.cs.handler;

import com.cs.config.BeanContext;
import com.cs.entity.RpcRequest;
import com.cs.service.UserServiceImpl;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.handler.timeout.IdleState;
import io.netty.handler.timeout.IdleStateEvent;

import java.lang.reflect.Field;
import java.lang.reflect.Method;


public class UserServerHandler extends ChannelInboundHandlerAdapter {


    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {

        // 判断是否符合约定，符合则调用本地方法，返回数据
        // msg:  UserService#sayHello#are you ok?
        if(msg instanceof RpcRequest){


            Class clazz = Class.forName(((RpcRequest) msg).getClassName());
            String methodName = ((RpcRequest) msg).getMethodName();
            Class<?>[] parameterTypes = ((RpcRequest) msg).getParameterTypes();
            Object[] parameters = ((RpcRequest) msg).getParameters();


            //spring容器中获取对应bean
            Object object =  BeanContext.getApplicationContext().getBean(clazz);
            //反射调用方法并写入参数
            Method method = object.getClass().getMethod(methodName,parameterTypes);
            Object obj = method.invoke(object, parameters);

            ctx.writeAndFlush(obj);

        }


    }

    public void userEventTriggered(ChannelHandlerContext ctx, Object evt) throws Exception {
        super.userEventTriggered(ctx, evt);
        if (evt instanceof IdleStateEvent) {  // 2
            IdleStateEvent event = (IdleStateEvent) evt;
            String type = "";
            if (event.state() == IdleState.READER_IDLE) {
                type = "read idle";
            } else if (event.state() == IdleState.WRITER_IDLE) {
                type = "write idle";
            } else if (event.state() == IdleState.ALL_IDLE) {
                type = "all idle";
            }


            System.out.println( ctx.channel().remoteAddress()+"超时类型：" + type);
        } else {
            super.userEventTriggered(ctx, evt);
        }
        ctx.close();
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        super.exceptionCaught(ctx, cause);
        ctx.close();
    }
}
